import type { TableData, TableInstance } from '@arco-design/web-vue';
import { Message, Modal } from '@arco-design/web-vue';
import type { Options as paginationOptions } from './usePagination';
import { useBreakpoint, usePagination } from '@/hooks';

interface Options<T, U> {
	formatResult?: (data: T[]) => U[];
	onSuccess?: () => void;
	immediate?: boolean;
	rowKey?: keyof T;
	paginationOption?: paginationOptions;
}

interface PaginationParams {
	page: number;
	size: number;
}
type Api<T> = (params: PaginationParams) => Promise<ApiRes<PageRes<T[]>>> | Promise<ApiRes<T[]>>;

export function useTable<T extends U, U = T>(api: Api<T>, options?: Options<T, U>) {
	const { formatResult, onSuccess, immediate, rowKey } = options || {};
	const { pagination, setTotal } = usePagination(() => getTableData(), options?.paginationOption);
	const loading = ref(false);
	const tableData: Ref<U[]> = ref([]);

	async function getTableData() {
		try {
			loading.value = true;
			const res = await api({ page: pagination.current, size: pagination.pageSize });
			const data = !Array.isArray(res.data) ? res.data.list : res.data;
			tableData.value = formatResult ? formatResult(data) : data;
			const total = !Array.isArray(res.data) ? res.data.total : data.length;
			setTotal(total);
			onSuccess && onSuccess();
		} finally {
			loading.value = false;
		}
	}

	// 是否立即触发
	const isImmediate = immediate ?? true;
	isImmediate && getTableData();

	// 多选
	const selectedKeys = ref<(string | number)[]>([]);
	const select: TableInstance['onSelect'] = (rowKeys) => {
		if (Array.isArray(rowKey)) {
			selectedKeys.value = rowKeys;
		}
	};

	// 全选
	const selectAll: TableInstance['onSelectAll'] = (checked) => {
		const key = rowKey ?? 'id';
		const arr = (tableData.value as TableData[]).filter((i) => !(i?.disabled ?? false));
		selectedKeys.value = checked ? arr.map((i) => i[key as string]) : [];
	};

	// 查询
	const search = () => {
		selectedKeys.value = [];
		pagination.onChange(1);
	};

	// 刷新
	const refresh = () => {
		getTableData();
	};

	// 删除
	const handleDelete = async <T>(
		deleteApi: () => Promise<ApiRes<T>>,
		options?: { title?: string; content?: string; successTip?: string; showModal?: boolean; multiple?: boolean }
	): Promise<boolean | undefined> => {
		const onDelete = async () => {
			try {
				const res = await deleteApi();
				if (res.success) {
					// 计算新总页数
					const deleteNum = options?.multiple ? selectedKeys.value.length : 1;
					const totalPage = Math.ceil((pagination.total - deleteNum) / pagination.pageSize);
					// 修正当前页码
					if (pagination.current > totalPage) {
						pagination.current = totalPage > 0 ? totalPage : 1;
					}
					options?.multiple && (selectedKeys.value = []);
					Message.success(options?.successTip || '删除成功');
					await getTableData();
				}
				return res.success;
			} catch (error) {
				return false;
			}
		};
		const flag = options?.showModal ?? true; // 是否显示对话框
		if (!flag) {
			return onDelete();
		}
		Modal.warning({
			title: options?.title || '提示',
			content: options?.content || '是否确定删除该条数据？',
			okButtonProps: { status: 'danger' },
			hideCancel: false,
			maskClosable: false,
			onBeforeOk: onDelete
		});
	};

	const { breakpoint } = useBreakpoint();
	// 表格操作列在小屏下不固定在右侧
	const fixed = computed(() => (!['xs', 'sm'].includes(breakpoint.value) ? 'right' : undefined));

	return {
		/** 表格加载状态 */
		loading,
		/** 表格数据 */
		tableData,
		/** 获取表格数据 */
		getTableData,
		/** 搜索，页码会重置为1 */
		search,
		/** 分页的传参 */
		pagination,
		/** 选择的行keys */
		selectedKeys,
		/** 选择行 */
		select,
		/** 全选行 */
		selectAll,
		/** 处理删除、批量删除 */
		handleDelete,
		/** 刷新表格数据，页码会缓存 */
		refresh,
		/** 操作列在小屏场景下不固定在右侧 */
		fixed
	};
}
